package com.ekuaitu.kuaitu.ble;

import android.util.Log;

import com.inuker.bluetooth.library.connect.options.BleConnectOptions;
import com.inuker.bluetooth.library.connect.response.BleConnectResponse;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.response.SearchResponse;

import java.util.Arrays;
import java.util.UUID;

import static com.inuker.bluetooth.library.Constants.REQUEST_FAILED;
import static com.inuker.bluetooth.library.Constants.REQUEST_SUCCESS;

/**
 * Created by jieyaozu on 2017/5/4.
 */

public class BluetoothHelper implements BleNotify.BlueNotifyCallBack {
    private String btMac;
    private byte[] btToken = new byte[4];
    byte[] loadPwd = new byte[6];
    byte[] loadKey = new byte[16];
    private static BluetoothHelper bluetoothHelper;
    private BluetoothCommandCallback commandCallback;

    public void setBluetoothCommandCallback(BluetoothCommandCallback bluetoothCommandCallback) {
        this.commandCallback = bluetoothCommandCallback;
    }

    public void searchDevice(SearchResponse mSearchResponse, BluetoothCommandCallback bluetoothCommandCallback) {
        searchDevice(mSearchResponse);
        setBluetoothCommandCallback(bluetoothCommandCallback);
    }

    public static BluetoothHelper getInstance() {
        if (bluetoothHelper == null) {
            bluetoothHelper = new BluetoothHelper();
        }
        return bluetoothHelper;
    }

    /**
     * 第一步
     * 搜索蓝牙设备
     */
    public void searchDevice(SearchResponse mSearchResponse) {
        SearchRequest request = new SearchRequest.Builder().searchBluetoothLeDevice(10000, 1).build();
        ClientManager.getClient().search(request, mSearchResponse);
    }


    /**
     * 第二步
     * 连接设备
     *
     * @param mac
     * @param loadPwd
     * @param loadKey
     */
    public void connectDevice(final String mac, byte[] loadPwd, byte[] loadKey, final OnConnectListener listener) {
        Log.i("scanresult", "inUse正在连接" + mac);
        btMac = mac;
        System.arraycopy(loadPwd, 0, this.loadPwd, 0, 6);
        System.arraycopy(loadKey, 0, this.loadKey, 0, 16);

        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(2)
                .setConnectTimeout(10000)
                .setServiceDiscoverRetry(2)
                .setServiceDiscoverTimeout(7000)
                .build();

        //发起连接
        ClientManager.getClient().connect(mac, options, new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile profile) {
                if (code == REQUEST_SUCCESS) {
                    Log.i("scanresult", "inUse连接成功" + mac);
                    if (listener != null) {
                        listener.onConnectSuccess();
                    }
                    bluetoothGetToken();
                } else if (code == REQUEST_FAILED) {
                    Log.i("scanresultInput", "inUse连接结果" + code);
                    if (listener != null) {
                        listener.onConnectFailed();
                    }
                }
            }
        });
        BleNotify.getInstance().setBleNotifyCallBack(this);
        ClientManager.getClient().notify(mac, BlueUtils.serverUUID, BlueUtils.readDataUUID, BleNotify.getInstance().getBleNotifyResponse());
    }

    /**
     * 获得当前连接的设置mac
     *
     * @return
     */
    public String getCurrentConnectMac() {
        return btMac;
    }

    public byte[] getConnectToken() {
        return btToken;
    }

    /**
     * 由于有些地方没有用到这个工具类，所以如果锁之前通过其它方式已经连接过了，
     * 就不再需要执行第一步(searchDevice 方法)了,而是要把所需数据加载进来
     */
    public void loadLockData(String mac, byte[] token, byte[] pwd, byte[] key) {
        this.btMac = mac;
        if (token != null) System.arraycopy(token, 0, this.btToken, 0, 4);
        if (pwd != null) System.arraycopy(pwd, 0, this.loadPwd, 0, 6);
        if (key != null) System.arraycopy(key, 0, this.loadKey, 0, 16);
        BleNotify.getInstance().setBleNotifyCallBack(this);
    }

    /**
     * 重新设置一下notify的回调
     *
     * @param mac
     */
    public void resetNotifyCallback(String mac) {
        BleNotify.getInstance().setBleNotifyCallBack(this);
    }

    public void setConnectToken(byte[] token) {
        System.arraycopy(token, 0, this.btToken, 0, 4);
    }

    /***
     * token是否为空
     *
     * @return
     */
    public boolean connectTokenIsEmpty() {
        if (btToken[0] == 0 && btToken[1] == 0 && btToken[2] == 0 && btToken[3] == 0) {
            return true;
        }
        return false;
    }

    public boolean isConnect() {
        return ClientManager.getClient().getConnectStatus(btMac) == 2;
    }

    @Override
    public void onNotify(UUID service, UUID character, byte[] value) {
        byte[] x = new byte[16];
        System.arraycopy(value, 0, x, 0, 16);
        byte[] mingwen = BlueUtils.decrypt(x, loadKey);
        if (mingwen != null && mingwen.length == 16) {
            if (mingwen[0] == 0x06 && mingwen[1] == 0x02) {//获取TOKEN响应
                Log.i("====token====>", Arrays.toString(mingwen));
                btToken[0] = mingwen[3];
                btToken[1] = mingwen[4];
                btToken[2] = mingwen[5];
                btToken[3] = mingwen[6];
                if (commandCallback != null) {
                    commandCallback.onGetToken(btToken);
                }
            } else if (mingwen[0] == 0x05 && mingwen[1] == 0x15 && mingwen[2] == 0x01) {  //设置还车模式响应
                if (commandCallback != null) {
                    commandCallback.onSetReturnMode(mingwen[3] == 0x00);
                }
            } else if (mingwen[0] == 0x05 && mingwen[1] == 0x02 && mingwen[2] == 0x01) {//开锁命令响应
                if (commandCallback != null) {
                    commandCallback.onOpenLock(mingwen[3] == 0x00);
                }
            } else if (mingwen[0] == 0x05 && mingwen[1] == 0x08) {//关锁通知响应
                if (commandCallback != null) {
                    commandCallback.onCloseLock(mingwen[3] == 0x00);
                }
            } else if (mingwen[0] == 0x05 && mingwen[1] == 0x0d) {
                if (commandCallback != null) {
                    commandCallback.onResetLock(mingwen[3] == 0x00);
                }
            } else if (mingwen[0] == 0x02 && mingwen[1] == 0x02 && mingwen[2] == 0x01) {//查询电量指令响应
                if (commandCallback != null) {
                    commandCallback.onGetLockPower(mingwen[3]);
                }
            } else if (mingwen[0] == 0x05 && mingwen[1] == 0x0f && mingwen[2] == 0x01) {//查询锁状态指令响应
                if (commandCallback != null) {
                    commandCallback.onCheckLockStatus(mingwen[3] == 0x00);
                }
            }
        }
    }

    public interface BluetoothCommandCallback {
        /**
         * 设置还车模式响应
         *
         * @param isSuccessful
         */
        void onSetReturnMode(boolean isSuccessful);

        /**
         * 连接成功后会获取TOKEN
         *
         * @param btToken
         */
        void onGetToken(byte[] btToken);

        void onOpenLock(boolean isSuccessful);

        void onCloseLock(boolean isSuccessful);

        void onResetLock(boolean isSuccessful);

        void onGetLockPower(byte power);

        void onCheckLockStatus(boolean isOpen);
    }

    public interface OnConnectListener {
        void onConnectSuccess();

        void onConnectFailed();
    }

    /**
     * 查询锁的GSMID
     */
    public void findGSMID() {
        byte[] status = {0x05, 0x23, 0x01, 0x00, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(status, loadKey, btMac);
    }

    /**
     * 查询锁的工作模式
     */
    public void findWorkMode() {
        byte[] data = {0x05, 0x20, 0x01, 0x00, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(data, loadKey, btMac);
    }

    /**
     * 设置锁的工作模式
     *
     * @param mode 十六进制数据: 0x00 正常模式，0x01运输模式，0x02锁重启
     */
    public void setWorkMode(byte mode) {
        byte[] data = {0x05, 0x21, 0x01, mode, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(data, loadKey, btMac);
    }

    /**
     * 开锁
     */
    public void openLock() {
        byte[] openLock = {0x05, 0x01, 0x06, loadPwd[0], loadPwd[1], loadPwd[2], loadPwd[3], loadPwd[4], loadPwd[5], btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00};
        BlueUtils.sendData(openLock, loadKey, btMac);
    }

    /**
     * 复位命令
     */
    public void resetLock() {
        byte[] resetLock = {0x05, 0x0c, 0x01, 0x01, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(resetLock, loadKey, btMac);
    }

    /**
     * 查询电量
     */
    public void checkDianLiang() {
        byte[] dianLiang = {0x02, 0x01, 0x01, 0x01, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(dianLiang, loadKey, btMac);
    }

    /**
     * 蓝牙命令：获取token
     */
    public void bluetoothGetToken() {
        byte[] getToken = {0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(getToken, loadKey, btMac);
    }

    /**
     * 查询锁的状态
     */
    public void checkStatus() {
        byte[] status = {0x05, 0x0e, 0x01, 0x01, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(status, loadKey, btMac);
    }

    /**
     * 设置为还车状态
     */
    public void setReturnStatus() {
        byte[] status = {0x05, 0x14, 0x01, 0x01, btToken[0], btToken[1], btToken[2], btToken[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        BlueUtils.sendData(status, loadKey, btMac);
    }

}
